#pragma once

#if 0


namespace Graph
{
	namespace BFS
	{
		struct Define;
		struct VertexResult;
	}

	namespace DFS
	{
		struct CallBack;
		struct Define;
		struct Result;
		struct VertexResult;
	}

	enum OptType
	{
		OptType_None,
		OptType_AddVertex,
		OptType_AddEdge,
		OptType_AddUEdge,
		OptType_CalcBFS,
		OptType_FillOs,
	};

	template <typename T>
	struct Opt;
	struct Vertex;

	struct Manager : public ObjectT<Manager>
	{
		template<typename T = void, typename... Args>
		Manager& addVertex(size_t id, Args&&... args);
		Manager& addEdge(size_t id1, size_t id2);
		Manager& addUEdge(size_t id1, size_t id2);
		void calcBFS(size_t srcId, size_t resId);
		void calcBFS(BFS::Define&& def);
		void calcDFS(DFS::Define&& def);
		std::ostream& fillOs(std::ostream& os) const override;

		auto emplaceDFSResult(size_t id)->DFS::Result*;
		auto getVertex(size_t id)->Vertex*;
		template<typename T = void >
		Opt<T> opt(OptType o = OptType_None) { return Opt<T>{o, * this}; }
	};

	struct Data : public ObjectT<Data>
	{
		std::ostream& fillOs(std::ostream& os) const override;
	};

	struct Edges : public ObjectT<Edges>
	{
		std::unordered_set<ObjId> _data;
		std::ostream& fillOs(std::ostream& os) const override;
	};

	struct Vertex : public ObjectT<Vertex>
	{
		template<typename T = void, typename... Args>
		Vertex& addVertex(Args&&... args);
		Vertex& addEdge(ObjId id);
		Edges* getEdges();
		auto getBFSResult(ObjId id)->BFS::VertexResult*;
		auto visitDFS(ObjId parId, ObjId id)->bool;
		auto fillSelfOs(std::ostream& os) const->std::ostream & override;
		auto fillChildenOs(std::ostream& os) const->std::ostream& override;
	};

	template<typename T = void>
	struct Opt
	{
		OptType _opt = OptType_None;
		Manager& _inst;
		Opt(OptType opt, Manager& inst) : _opt(opt), _inst(inst) {}

		template <typename U>
		Opt<U> change() { return Opt<U>{_opt, _inst}; }
		template<typename... Args>
		Opt& operator() (Args&&... args);
		Opt& operator() (OptType o);
	};
}
#endif // 0
#if 0

struct Graph
{
	std::unordered_map<size_t, GraphDetail::Vertex> _vert;

	template<typename... Args>
	void addVertex(size_t id, Args... args);
	bool calcDFS(DFSForest<T>& forest);
	bool visitDFS(Vertex<T>& vert, DFSForest<T>& forest, DFSTree<T>*& pTree, DFSTree<T>* pTreeParent = nullptr);
	bool calcTopologicalSort(TopologicalSort<T>& sort);
};

#endif
#include "GraphImpl.h"
